/*
 * @Author: 0x9DEFA478
 * @Date: 2022-01-22 23:05:55
 * @LastEditTime: 2022-03-06 17:21:26
 * @LastEditors: 0x9DEFA478
 * @Description: 
 * QQ:2652450237
 * ============================================================================================================================================
 * 
 * 
 * 
 *                                                                                               ************      ****************************
 *                                                                                             ************      ****************************  
 *                                                                                           ************      ****************************    
 *                                                                                         ************      ****************************      
 *                                                                                       ************      ************                        
 *                                                                                     ************      ************                          
 *                                                                                   ************      ************                            
 *                                                                                 ************      ************                              
 *                                                                               ************      ************                                
 *                                                                             ************      ************                                  
 *                                                                           ************      ************                                    
 *                                                                         ************      ************                                      
 *                                                                       ************      ************                                        
 *                                                                     ************      ************                                          
 *                                                                   ************      ************                                            
 *                                                                 ************      ************                                              
 *                                                               ************      ************                                                
 *                                                             ************      ************                                                  
 *                                                           ************      ************                                                    
 *                                                         ************      ************                                                      
 *                                                       ************      ************                                                        
 *                                                     ************      ************                                                          
 *                                                   ************      ************                                                            
 *                                                 ************      ************                                                              
 *                                               ************      ************                                                                
 *                                             ************      ************                                                                  
 *                                           ************      ************                                                                    
 *                                         ************      ************                                                                      
 *                                       ************      ************                                                                        
 *                                     ************      ************                                                                          
 *                                   ************      ************                                                                            
 *                                 ************      ************                                                                              
 *                               ************      ************                                                                                
 *                             ************      ************                                                                                  
 *                           ************      ************                                                                                    
 *                         ************      ************                                                                                      
 *       ****************************      ************                                                                                        
 *     ****************************      ************                                                                                          
 *   ****************************      ************                                                                                            
 * ****************************      ************                                                                                              
 * 
 * 
 * 
 * ============================================================================================================================================
 * 
 */
#include "./H_NES_Console.h"
#include "../ConstString/H_NES_ConstString.h"




static Hbyte ReverseBitTable[256]={
  0x00U,0x80U,0x40U,0xC0U,0x20U,0xA0U,0x60U,0xE0U,0x10U,0x90U,0x50U,0xD0U,0x30U,0xB0U,0x70U,0xF0U,
  0x08U,0x88U,0x48U,0xC8U,0x28U,0xA8U,0x68U,0xE8U,0x18U,0x98U,0x58U,0xD8U,0x38U,0xB8U,0x78U,0xF8U,
  0x04U,0x84U,0x44U,0xC4U,0x24U,0xA4U,0x64U,0xE4U,0x14U,0x94U,0x54U,0xD4U,0x34U,0xB4U,0x74U,0xF4U,
  0x0CU,0x8CU,0x4CU,0xCCU,0x2CU,0xACU,0x6CU,0xECU,0x1CU,0x9CU,0x5CU,0xDCU,0x3CU,0xBCU,0x7CU,0xFCU,
  0x02U,0x82U,0x42U,0xC2U,0x22U,0xA2U,0x62U,0xE2U,0x12U,0x92U,0x52U,0xD2U,0x32U,0xB2U,0x72U,0xF2U,
  0x0AU,0x8AU,0x4AU,0xCAU,0x2AU,0xAAU,0x6AU,0xEAU,0x1AU,0x9AU,0x5AU,0xDAU,0x3AU,0xBAU,0x7AU,0xFAU,
  0x06U,0x86U,0x46U,0xC6U,0x26U,0xA6U,0x66U,0xE6U,0x16U,0x96U,0x56U,0xD6U,0x36U,0xB6U,0x76U,0xF6U,
  0x0EU,0x8EU,0x4EU,0xCEU,0x2EU,0xAEU,0x6EU,0xEEU,0x1EU,0x9EU,0x5EU,0xDEU,0x3EU,0xBEU,0x7EU,0xFEU,
  0x01U,0x81U,0x41U,0xC1U,0x21U,0xA1U,0x61U,0xE1U,0x11U,0x91U,0x51U,0xD1U,0x31U,0xB1U,0x71U,0xF1U,
  0x09U,0x89U,0x49U,0xC9U,0x29U,0xA9U,0x69U,0xE9U,0x19U,0x99U,0x59U,0xD9U,0x39U,0xB9U,0x79U,0xF9U,
  0x05U,0x85U,0x45U,0xC5U,0x25U,0xA5U,0x65U,0xE5U,0x15U,0x95U,0x55U,0xD5U,0x35U,0xB5U,0x75U,0xF5U,
  0x0DU,0x8DU,0x4DU,0xCDU,0x2DU,0xADU,0x6DU,0xEDU,0x1DU,0x9DU,0x5DU,0xDDU,0x3DU,0xBDU,0x7DU,0xFDU,
  0x03U,0x83U,0x43U,0xC3U,0x23U,0xA3U,0x63U,0xE3U,0x13U,0x93U,0x53U,0xD3U,0x33U,0xB3U,0x73U,0xF3U,
  0x0BU,0x8BU,0x4BU,0xCBU,0x2BU,0xABU,0x6BU,0xEBU,0x1BU,0x9BU,0x5BU,0xDBU,0x3BU,0xBBU,0x7BU,0xFBU,
  0x07U,0x87U,0x47U,0xC7U,0x27U,0xA7U,0x67U,0xE7U,0x17U,0x97U,0x57U,0xD7U,0x37U,0xB7U,0x77U,0xF7U,
  0x0FU,0x8FU,0x4FU,0xCFU,0x2FU,0xAFU,0x6FU,0xEFU,0x1FU,0x9FU,0x5FU,0xDFU,0x3FU,0xBFU,0x7FU,0xFFU
};




#define H_NES_PPU_Process_vIncX(_in_Console,_temp_v,_temp_t_uint16) \
do{\
  _temp_v=_in_Console->PPU.Register.Internal.v;\
  if((_temp_v&0x001FU)==0x001FU){\
    _temp_v=(_temp_v&0xFFE0U)^0x0400U;\
  }else{\
    _temp_v+=0x0001U;\
  }\
  _in_Console->PPU.Register.Internal.v=_temp_v;\
}while(0)

#define H_NES_PPU_Process_vIncYSetX(_in_Console,_temp_v,_temp_t_uint16) \
do{\
  _temp_v=_in_Console->PPU.Register.Internal.v;\
  if((_temp_v&0x7000U)==0x7000U){\
    _temp_v&=0x0FFF;\
    _temp_t_uint16=(_temp_v>>5)&0x001FU;\
    if(_temp_t_uint16==0x001DU){\
      _temp_v=(_temp_v&0xFC1FU)^0x0800U;\
    }else if(_temp_t_uint16==0x001FU){\
      _temp_v=_temp_v&0xFC1FU;\
    }else{\
      _temp_v+=0x0020U;\
    }\
  }else{\
    _temp_v+=0x1000U;\
  }\
  _temp_t_uint16=_in_Console->PPU.Register.Internal.t;\
  _temp_v=(_temp_v&(~0x041FU))|(_temp_t_uint16&0x041FU);\
  _in_Console->PPU.Register.Internal.v=_temp_v;\
}while(0)




static void Background_PreFetch_First(unsigned int BufferIndex,Hbyte PPUMASK,H_NES_Console* Console);
static void Background_PreFetch_Mid(unsigned int BufferIndex,H_NES_Console* Console);
static void Background_PreFetch_Last(H_NES_Console* Console);
static void Background_Renders(unsigned int BufferIndex,H_NES_Console* Console);
static Hbyte OAM_PreFetch(unsigned int line,H_NES_Console* Console);
static void Sprite_Renders(unsigned int BufferIndex,H_NES_Console* Console);




void H_NES_PPU_RendrsFrame_NTSC(H_NES_Console* Console){

#define oH_NES_CPU_Execute(_in_PPUCLK,_in_Console) \
  H_NES_CPU_Execute_NTSC((_in_PPUCLK)*vH_NES_PPU_NTSC_MCLKDiv,_in_Console)

  unsigned int line;

  Huint16 t_uint16;
  Hint32 Cycle;

  Hbyte PPUCTRL;
  Hbyte PPUMASK;
  Huint16 v;
  
  unsigned int BufferIndex;

  Hbyte MemLoc;
  int Shift;
  void (*MMC3_A12_Rise)(unsigned int,void*);
  Hint32 MMC4_CountDelay;


  MMC3_A12_Rise=Console->Cartridge.Option.MMC3_A12_Rise;
  MMC4_CountDelay=Console->CompatibilityOption.MMC4_CountDelay;

  //0,0 0,0
  if(Console->PPU.Renderer.IsOddFrame!=0){
    Console->PPU.Renderer.IsOddFrame=0;
  }else{
    Console->PPU.Renderer.IsOddFrame=-1;
    oH_NES_CPU_Execute(1,Console);
  }

  //0,1 0,240
  for(BufferIndex=0U;BufferIndex<30U;BufferIndex++){
    
    oH_NES_CPU_Execute(8,Console);
    PPUMASK=Console->PPU.Register.Register[vH_NES_PPU_Register_PPUMASK];
    if((PPUMASK&(vH_NES_PPU_PPUMASK_b|vH_NES_PPU_PPUMASK_s))!=0U){

      //背景预取
      if((PPUMASK&vH_NES_PPU_PPUMASK_b)!=0U){
        Background_PreFetch_Mid(BufferIndex+2U,Console);
      }

      //渲染
      Background_Renders(BufferIndex,Console);

      H_NES_PPU_Process_vIncX(Console,v,t_uint16);
    }
  }

  //0,241 0,248
  oH_NES_CPU_Execute(8,Console);
  PPUMASK=Console->PPU.Register.Register[vH_NES_PPU_Register_PPUMASK];
  if((PPUMASK&(vH_NES_PPU_PPUMASK_b|vH_NES_PPU_PPUMASK_s))!=0U){

    //背景预取
    if((PPUMASK&vH_NES_PPU_PPUMASK_b)!=0U){
      Background_PreFetch_Last(Console);
    }

    //渲染
    Background_Renders(30U,Console);

    H_NES_PPU_Process_vIncX(Console,v,t_uint16);
  }

  //0,249 0,260
  oH_NES_CPU_Execute(8,Console);
  PPUMASK=Console->PPU.Register.Register[vH_NES_PPU_Register_PPUMASK];
  if((PPUMASK&(vH_NES_PPU_PPUMASK_b|vH_NES_PPU_PPUMASK_s))!=0U){

    //渲染
    Background_Renders(31U,Console);

    H_NES_PPU_Process_vIncYSetX(Console,v,t_uint16);
  }
  oH_NES_CPU_Execute(4,Console);

  //0,261 0,324
  PPUMASK=Console->PPU.Register.Register[vH_NES_PPU_Register_PPUMASK];
  if((PPUMASK&(vH_NES_PPU_PPUMASK_b|vH_NES_PPU_PPUMASK_s))!=0U){
    
    //OAM预取
    MemLoc=OAM_PreFetch(0U,Console);

    //MMC3 A12判定
    if(MMC3_A12_Rise!=NULL){
      PPUCTRL=Console->PPU.Register.Register[vH_NES_PPU_Register_PPUCTRL];

      //大约260~261
      if(MMC4_CountDelay>0){
        oH_NES_CPU_Execute(MMC4_CountDelay,Console);
      }
      Cycle=64-MMC4_CountDelay;
      if(((PPUCTRL&vH_NES_PPU_PPUCTRL_B)==0U)&&((MemLoc&0x01U)!=0U)){
        MMC3_A12_Rise(line,Console);
      }
      if(Cycle>0){
        Cycle-=8;
        oH_NES_CPU_Execute(8,Console);
      }
      //每两个精灵获取之间的间隙(8个精灵共7个间隙)
      for(Shift=0;Shift<6;Shift++){
        if(((MemLoc>>Shift)&0x03U)==0x02U){
          MMC3_A12_Rise(line,Console);
        }
        if(Cycle>0){
          Cycle-=8;
          oH_NES_CPU_Execute(8,Console);
        }
      }
      if(((MemLoc>>6)&0x03U)==0x02U){
        MMC3_A12_Rise(line,Console);
      }
      if(Cycle>0){
        Cycle-=8;
        oH_NES_CPU_Execute(8,Console);
      }
      if(((MemLoc&0x80U)==0U)&&((PPUCTRL&vH_NES_PPU_PPUCTRL_B)!=0U)){
        MMC3_A12_Rise(line,Console);
      }
      if(Cycle>0){
        oH_NES_CPU_Execute(Cycle,Console);
      }

    }else{
      oH_NES_CPU_Execute(64,Console);
    }
  
  }else{
    oH_NES_CPU_Execute(64,Console);
    for(BufferIndex=0;BufferIndex<256;BufferIndex++){
      Console->PPU.LineBuffer_Output[BufferIndex]=0x3FU;
    }
  }
  //输出一行的 数据
  Console->LL_Function.Console.RendersLine(Console->LL_Function.v,Console->PPU.LineBuffer_Output,0);

  //0,325 0,328
  oH_NES_CPU_Execute(4,Console);
  for(BufferIndex=0;BufferIndex<32;BufferIndex++){
    Console->PPU.Renderer.LineBuffer_Background[BufferIndex]=0U;
  }
  PPUMASK=Console->PPU.Register.Register[vH_NES_PPU_Register_PPUMASK];
  if((PPUMASK&(vH_NES_PPU_PPUMASK_b|vH_NES_PPU_PPUMASK_s))!=0U){
    
    //背景预取
    if((PPUMASK&vH_NES_PPU_PPUMASK_b)!=0U){
      Background_PreFetch_First(0U,PPUMASK,Console);
    }

    H_NES_PPU_Process_vIncX(Console,v,t_uint16);
  }

  //0,329 0,336
  oH_NES_CPU_Execute(8,Console);
  PPUMASK=Console->PPU.Register.Register[vH_NES_PPU_Register_PPUMASK];
  if((PPUMASK&(vH_NES_PPU_PPUMASK_b|vH_NES_PPU_PPUMASK_s))!=0U){
    
    //背景预取
    if((PPUMASK&vH_NES_PPU_PPUMASK_b)!=0U){
      Background_PreFetch_First(1U,PPUMASK,Console);
    }

    H_NES_PPU_Process_vIncX(Console,v,t_uint16);
  }

  //0,337 0,340
  oH_NES_CPU_Execute(4,Console);




  //1,0 239,340
  for(line=1U;line<240U;line++){

    //line,0 line,0
    oH_NES_CPU_Execute(1,Console);

    //line,1 line,240
    for(BufferIndex=0U;BufferIndex<30U;BufferIndex++){
    
      oH_NES_CPU_Execute(8,Console);
      PPUMASK=Console->PPU.Register.Register[vH_NES_PPU_Register_PPUMASK];
      if((PPUMASK&(vH_NES_PPU_PPUMASK_b|vH_NES_PPU_PPUMASK_s))!=0U){

        //背景预取
        if((PPUMASK&vH_NES_PPU_PPUMASK_b)!=0U){
          Background_PreFetch_Mid(BufferIndex+2U,Console);
        }

        //渲染
        if(((PPUMASK&vH_NES_PPU_PPUMASK_s)!=0U)&&((BufferIndex!=0U)||((PPUMASK&vH_NES_PPU_PPUMASK_M)!=0U))){
          //允许渲染
          Sprite_Renders(BufferIndex,Console);
        }else{
          Background_Renders(BufferIndex,Console);
        }

        H_NES_PPU_Process_vIncX(Console,v,t_uint16);
      }
    }

    //line,241 line,248
    oH_NES_CPU_Execute(8,Console);
    PPUMASK=Console->PPU.Register.Register[vH_NES_PPU_Register_PPUMASK];
    if((PPUMASK&(vH_NES_PPU_PPUMASK_b|vH_NES_PPU_PPUMASK_s))!=0U){

      //背景预取
      if((PPUMASK&vH_NES_PPU_PPUMASK_b)!=0U){
        Background_PreFetch_Last(Console);
      }

      //渲染
      if((PPUMASK&vH_NES_PPU_PPUMASK_s)!=0U){
        //允许渲染
        Sprite_Renders(30U,Console);
      }else{
        Background_Renders(30U,Console);
      }

      H_NES_PPU_Process_vIncX(Console,v,t_uint16);
    }

    //line,249 line,260
    oH_NES_CPU_Execute(8,Console);
    PPUMASK=Console->PPU.Register.Register[vH_NES_PPU_Register_PPUMASK];
    if((PPUMASK&(vH_NES_PPU_PPUMASK_b|vH_NES_PPU_PPUMASK_s))!=0U){

      //渲染
      if((PPUMASK&vH_NES_PPU_PPUMASK_s)!=0U){
        //允许渲染
        Sprite_Renders(31U,Console);
      }else{
        Background_Renders(31U,Console);
      }

      H_NES_PPU_Process_vIncYSetX(Console,v,t_uint16);
    }
    oH_NES_CPU_Execute(4,Console);

    //line,261 line,324
    PPUMASK=Console->PPU.Register.Register[vH_NES_PPU_Register_PPUMASK];
    if((PPUMASK&(vH_NES_PPU_PPUMASK_b|vH_NES_PPU_PPUMASK_s))!=0U){
      
      //OAM预取
      MemLoc=OAM_PreFetch(line,Console);

      //MMC3 A12判定
      if(MMC3_A12_Rise!=NULL){
        PPUCTRL=Console->PPU.Register.Register[vH_NES_PPU_Register_PPUCTRL];

        //大约260~261
        if(MMC4_CountDelay>0){
          oH_NES_CPU_Execute(MMC4_CountDelay,Console);
        }
        Cycle=64-MMC4_CountDelay;
        if(((PPUCTRL&vH_NES_PPU_PPUCTRL_B)==0U)&&((MemLoc&0x01U)!=0U)){
          MMC3_A12_Rise(line,Console);
        }
        if(Cycle>0){
          Cycle-=8;
          oH_NES_CPU_Execute(8,Console);
        }
        //每两个精灵获取之间的间隙(8个精灵共7个间隙)
        for(Shift=0;Shift<6;Shift++){
          if(((MemLoc>>Shift)&0x03U)==0x02U){
            MMC3_A12_Rise(line,Console);
          }
          if(Cycle>0){
            Cycle-=8;
            oH_NES_CPU_Execute(8,Console);
          }
        }
        if(((MemLoc>>6)&0x03U)==0x02U){
          MMC3_A12_Rise(line,Console);
        }
        if(Cycle>0){
          Cycle-=8;
          oH_NES_CPU_Execute(8,Console);
        }
        if(((MemLoc&0x80U)==0U)&&((PPUCTRL&vH_NES_PPU_PPUCTRL_B)!=0U)){
          MMC3_A12_Rise(line,Console);
        }
        if(Cycle>0){
          oH_NES_CPU_Execute(Cycle,Console);
        }

      }else{
        oH_NES_CPU_Execute(64,Console);
      }
    
    }else{
      oH_NES_CPU_Execute(64,Console);
      for(BufferIndex=0;BufferIndex<256;BufferIndex++){
        Console->PPU.LineBuffer_Output[BufferIndex]=0x3FU;
      }
    }
    //输出一行的 数据
    Console->LL_Function.Console.RendersLine(Console->LL_Function.v,Console->PPU.LineBuffer_Output,line);

    //line,324 line,328
    oH_NES_CPU_Execute(4,Console);
    for(BufferIndex=0;BufferIndex<32;BufferIndex++){
      Console->PPU.Renderer.LineBuffer_Background[BufferIndex]=0U;
    }
    PPUMASK=Console->PPU.Register.Register[vH_NES_PPU_Register_PPUMASK];
    if((PPUMASK&(vH_NES_PPU_PPUMASK_b|vH_NES_PPU_PPUMASK_s))!=0U){
      
      //背景预取
      if((PPUMASK&vH_NES_PPU_PPUMASK_b)!=0U){
        Background_PreFetch_First(0U,PPUMASK,Console);
      }

      H_NES_PPU_Process_vIncX(Console,v,t_uint16);
    }

    //line,329 line,336
    oH_NES_CPU_Execute(8,Console);
    PPUMASK=Console->PPU.Register.Register[vH_NES_PPU_Register_PPUMASK];
    if((PPUMASK&(vH_NES_PPU_PPUMASK_b|vH_NES_PPU_PPUMASK_s))!=0U){
      
      //背景预取
      if((PPUMASK&vH_NES_PPU_PPUMASK_b)!=0U){
        Background_PreFetch_First(1U,PPUMASK,Console);
      }

      H_NES_PPU_Process_vIncX(Console,v,t_uint16);
    }

    //line,337 line,341
    oH_NES_CPU_Execute(4,Console);
  }

  Console->PPU.Register.Internal.IsAddXY=0;

  //240,0 261,0
  oH_NES_CPU_Execute(341+1,Console);
  //Set Vblank
  Console->PPU.Register.Register[vH_NES_PPU_Register_PPUSTATUS]|=vH_NES_PPU_PPUSTATUS_V;
  Cycle=Console->CompatibilityOption.VblankNMI_Delay;
  if(Cycle>0){
    oH_NES_CPU_Execute(Cycle,Console);
  }
  //Suspend NMI
  if((Console->PPU.Register.Register[vH_NES_PPU_Register_PPUCTRL]&vH_NES_PPU_PPUCTRL_V)!=0U){
    Console->CPU.Status|=vH_NES_CPU_Status_NMI_Suspend;
  }
  Cycle=341*20 - Cycle;
  if(Cycle>0){
    oH_NES_CPU_Execute(Cycle,Console);
  }
  
  //261,1 261,260
  //Clear Vblank
  Console->PPU.Register.Register[vH_NES_PPU_Register_PPUSTATUS]&=(~(vH_NES_PPU_PPUSTATUS_V|vH_NES_PPU_PPUSTATUS_S|vH_NES_PPU_PPUSTATUS_O));
  Console->PPU.Register.Internal.IsAddXY=-1;
  oH_NES_CPU_Execute(260,Console);
  PPUMASK=Console->PPU.Register.Register[vH_NES_PPU_Register_PPUMASK];
  if((PPUMASK&(vH_NES_PPU_PPUMASK_b|vH_NES_PPU_PPUMASK_s))!=0U){
    H_NES_PPU_Process_vIncYSetX(Console,v,t_uint16);

    //MMC3 A12判定
    if(MMC3_A12_Rise!=NULL){
      PPUCTRL=Console->PPU.Register.Register[vH_NES_PPU_Register_PPUCTRL];
      if((PPUCTRL&(vH_NES_PPU_PPUCTRL_H|vH_NES_PPU_PPUCTRL_B|vH_NES_PPU_PPUCTRL_S))==vH_NES_PPU_PPUCTRL_S){
        MMC3_A12_Rise(261U,Console);
      }else if((PPUCTRL&(vH_NES_PPU_PPUCTRL_H|vH_NES_PPU_PPUCTRL_B))==vH_NES_PPU_PPUCTRL_H){
        MMC3_A12_Rise(261U,Console);
      }
    }
  }

  //261,261 261,304
  oH_NES_CPU_Execute(44,Console);
  PPUMASK=Console->PPU.Register.Register[vH_NES_PPU_Register_PPUMASK];
  if((PPUMASK&(vH_NES_PPU_PPUMASK_b|vH_NES_PPU_PPUMASK_s))!=0U){
    //vert(v) = vert(t)
    v=Console->PPU.Register.Internal.v;
    t_uint16=Console->PPU.Register.Internal.t;
    Console->PPU.Register.Internal.v=(v&(~0x7BE0U))|(t_uint16&0x7BE0U);
  }

  //261,305 261,324
  oH_NES_CPU_Execute(20,Console);
  PPUMASK=Console->PPU.Register.Register[vH_NES_PPU_Register_PPUMASK];
  if((PPUMASK&(vH_NES_PPU_PPUMASK_b|vH_NES_PPU_PPUMASK_s))!=0U){
    //MMC3 A12判定
    if(MMC3_A12_Rise!=NULL){
      PPUCTRL=Console->PPU.Register.Register[vH_NES_PPU_Register_PPUCTRL];
      if((PPUCTRL&(vH_NES_PPU_PPUCTRL_H|vH_NES_PPU_PPUCTRL_B|vH_NES_PPU_PPUCTRL_S))==vH_NES_PPU_PPUCTRL_B){
        MMC3_A12_Rise(261U,Console);
      }
    }
  }

  //261,325 261,328
  oH_NES_CPU_Execute(4,Console);
  for(BufferIndex=0;BufferIndex<32;BufferIndex++){
    Console->PPU.Renderer.LineBuffer_Background[BufferIndex]=0U;
  }
  PPUMASK=Console->PPU.Register.Register[vH_NES_PPU_Register_PPUMASK];
  if((PPUMASK&(vH_NES_PPU_PPUMASK_b|vH_NES_PPU_PPUMASK_s))!=0U){
    
    //背景预取
    if((PPUMASK&vH_NES_PPU_PPUMASK_b)!=0U){
      Background_PreFetch_First(0U,PPUMASK,Console);
    }

    H_NES_PPU_Process_vIncX(Console,v,t_uint16);
  }

  //261,329 261,336
  oH_NES_CPU_Execute(8,Console);
  PPUMASK=Console->PPU.Register.Register[vH_NES_PPU_Register_PPUMASK];
  if((PPUMASK&(vH_NES_PPU_PPUMASK_b|vH_NES_PPU_PPUMASK_s))!=0U){
    
    //背景预取
    if((PPUMASK&vH_NES_PPU_PPUMASK_b)!=0U){
      Background_PreFetch_First(1U,PPUMASK,Console);
    }

    H_NES_PPU_Process_vIncX(Console,v,t_uint16);
  }
  

  //261,337 261,341
  oH_NES_CPU_Execute(4,Console);

#undef oH_NES_CPU_Execute

}

void H_NES_PPU_RendrsFrame_PAL(H_NES_Console* Console){

#define oH_NES_CPU_Execute(_in_PPUCLK,_in_Console) \
  H_NES_CPU_Execute_PAL((_in_PPUCLK)*vH_NES_PPU_PAL_MCLKDiv,_in_Console)

  unsigned int line;

  Huint16 t_uint16;
  Hint32 Cycle;

  Hbyte PPUCTRL;
  Hbyte PPUMASK;
  Huint16 v;
  
  unsigned int BufferIndex;

  Hbyte MemLoc;
  int Shift;
  void (*MMC3_A12_Rise)(unsigned int,void*);
  Hint32 MMC4_CountDelay;


  MMC3_A12_Rise=Console->Cartridge.Option.MMC3_A12_Rise;
  MMC4_CountDelay=Console->CompatibilityOption.MMC4_CountDelay;

  //0,0 0,0
  if(Console->PPU.Renderer.IsOddFrame!=0){
    Console->PPU.Renderer.IsOddFrame=0;
  }else{
    Console->PPU.Renderer.IsOddFrame=-1;
  }
  oH_NES_CPU_Execute(1,Console);

  //0,1 0,240
  for(BufferIndex=0U;BufferIndex<30U;BufferIndex++){
    
    oH_NES_CPU_Execute(8,Console);
    PPUMASK=Console->PPU.Register.Register[vH_NES_PPU_Register_PPUMASK];
    if((PPUMASK&(vH_NES_PPU_PPUMASK_b|vH_NES_PPU_PPUMASK_s))!=0U){

      //背景预取
      if((PPUMASK&vH_NES_PPU_PPUMASK_b)!=0U){
        Background_PreFetch_Mid(BufferIndex+2U,Console);
      }

      //渲染
      Background_Renders(BufferIndex,Console);

      H_NES_PPU_Process_vIncX(Console,v,t_uint16);
    }
  }

  //0,241 0,248
  oH_NES_CPU_Execute(8,Console);
  PPUMASK=Console->PPU.Register.Register[vH_NES_PPU_Register_PPUMASK];
  if((PPUMASK&(vH_NES_PPU_PPUMASK_b|vH_NES_PPU_PPUMASK_s))!=0U){

    //背景预取
    if((PPUMASK&vH_NES_PPU_PPUMASK_b)!=0U){
      Background_PreFetch_Last(Console);
    }

    //渲染
    Background_Renders(30U,Console);

    H_NES_PPU_Process_vIncX(Console,v,t_uint16);
  }

  //0,249 0,260
  oH_NES_CPU_Execute(8,Console);
  PPUMASK=Console->PPU.Register.Register[vH_NES_PPU_Register_PPUMASK];
  if((PPUMASK&(vH_NES_PPU_PPUMASK_b|vH_NES_PPU_PPUMASK_s))!=0U){

    //渲染
    Background_Renders(31U,Console);

    H_NES_PPU_Process_vIncYSetX(Console,v,t_uint16);
  }
  oH_NES_CPU_Execute(4,Console);

  //0,261 0,324
  PPUMASK=Console->PPU.Register.Register[vH_NES_PPU_Register_PPUMASK];
  if((PPUMASK&(vH_NES_PPU_PPUMASK_b|vH_NES_PPU_PPUMASK_s))!=0U){
    
    //OAM预取
    MemLoc=OAM_PreFetch(0U,Console);

    //MMC3 A12判定
    if(MMC3_A12_Rise!=NULL){
      PPUCTRL=Console->PPU.Register.Register[vH_NES_PPU_Register_PPUCTRL];

      //大约260~261
      if(MMC4_CountDelay>0){
        oH_NES_CPU_Execute(MMC4_CountDelay,Console);
      }
      Cycle=64-MMC4_CountDelay;
      if(((PPUCTRL&vH_NES_PPU_PPUCTRL_B)==0U)&&((MemLoc&0x01U)!=0U)){
        MMC3_A12_Rise(line,Console);
      }
      if(Cycle>0){
        Cycle-=8;
        oH_NES_CPU_Execute(8,Console);
      }
      //每两个精灵获取之间的间隙(8个精灵共7个间隙)
      for(Shift=0;Shift<6;Shift++){
        if(((MemLoc>>Shift)&0x03U)==0x02U){
          MMC3_A12_Rise(line,Console);
        }
        if(Cycle>0){
          Cycle-=8;
          oH_NES_CPU_Execute(8,Console);
        }
      }
      if(((MemLoc>>6)&0x03U)==0x02U){
        MMC3_A12_Rise(line,Console);
      }
      if(Cycle>0){
        Cycle-=8;
        oH_NES_CPU_Execute(8,Console);
      }
      if(((MemLoc&0x80U)==0U)&&((PPUCTRL&vH_NES_PPU_PPUCTRL_B)!=0U)){
        MMC3_A12_Rise(line,Console);
      }
      if(Cycle>0){
        oH_NES_CPU_Execute(Cycle,Console);
      }

    }else{
      oH_NES_CPU_Execute(64,Console);
    }
  
  }else{
    oH_NES_CPU_Execute(64,Console);
    for(BufferIndex=0;BufferIndex<256;BufferIndex++){
      Console->PPU.LineBuffer_Output[BufferIndex]=0x3FU;
    }
  }
  //输出一行的 数据
  Console->LL_Function.Console.RendersLine(Console->LL_Function.v,Console->PPU.LineBuffer_Output,0);

  //0,325 0,328
  oH_NES_CPU_Execute(4,Console);
  for(BufferIndex=0;BufferIndex<32;BufferIndex++){
    Console->PPU.Renderer.LineBuffer_Background[BufferIndex]=0U;
  }
  PPUMASK=Console->PPU.Register.Register[vH_NES_PPU_Register_PPUMASK];
  if((PPUMASK&(vH_NES_PPU_PPUMASK_b|vH_NES_PPU_PPUMASK_s))!=0U){
    
    //背景预取
    if((PPUMASK&vH_NES_PPU_PPUMASK_b)!=0U){
      Background_PreFetch_First(0U,PPUMASK,Console);
    }

    H_NES_PPU_Process_vIncX(Console,v,t_uint16);
  }

  //0,329 0,336
  oH_NES_CPU_Execute(8,Console);
  PPUMASK=Console->PPU.Register.Register[vH_NES_PPU_Register_PPUMASK];
  if((PPUMASK&(vH_NES_PPU_PPUMASK_b|vH_NES_PPU_PPUMASK_s))!=0U){
    
    //背景预取
    if((PPUMASK&vH_NES_PPU_PPUMASK_b)!=0U){
      Background_PreFetch_First(1U,PPUMASK,Console);
    }

    H_NES_PPU_Process_vIncX(Console,v,t_uint16);
  }

  //0,337 0,340
  oH_NES_CPU_Execute(4,Console);




  //1,0 239,340
  for(line=1U;line<240U;line++){

    //line,0 line,0
    oH_NES_CPU_Execute(1,Console);

    //line,1 line,240
    for(BufferIndex=0U;BufferIndex<30U;BufferIndex++){
    
      oH_NES_CPU_Execute(8,Console);
      PPUMASK=Console->PPU.Register.Register[vH_NES_PPU_Register_PPUMASK];
      if((PPUMASK&(vH_NES_PPU_PPUMASK_b|vH_NES_PPU_PPUMASK_s))!=0U){

        //背景预取
        if((PPUMASK&vH_NES_PPU_PPUMASK_b)!=0U){
          Background_PreFetch_Mid(BufferIndex+2U,Console);
        }

        //渲染
        if(((PPUMASK&vH_NES_PPU_PPUMASK_s)!=0U)&&((BufferIndex!=0U)||((PPUMASK&vH_NES_PPU_PPUMASK_M)!=0U))){
          //允许渲染
          Sprite_Renders(BufferIndex,Console);
        }else{
          Background_Renders(BufferIndex,Console);
        }

        H_NES_PPU_Process_vIncX(Console,v,t_uint16);
      }
    }

    //line,241 line,248
    oH_NES_CPU_Execute(8,Console);
    PPUMASK=Console->PPU.Register.Register[vH_NES_PPU_Register_PPUMASK];
    if((PPUMASK&(vH_NES_PPU_PPUMASK_b|vH_NES_PPU_PPUMASK_s))!=0U){

      //背景预取
      if((PPUMASK&vH_NES_PPU_PPUMASK_b)!=0U){
        Background_PreFetch_Last(Console);
      }

      //渲染
      if((PPUMASK&vH_NES_PPU_PPUMASK_s)!=0U){
        //允许渲染
        Sprite_Renders(30U,Console);
      }else{
        Background_Renders(30U,Console);
      }

      H_NES_PPU_Process_vIncX(Console,v,t_uint16);
    }

    //line,249 line,260
    oH_NES_CPU_Execute(8,Console);
    PPUMASK=Console->PPU.Register.Register[vH_NES_PPU_Register_PPUMASK];
    if((PPUMASK&(vH_NES_PPU_PPUMASK_b|vH_NES_PPU_PPUMASK_s))!=0U){

      //渲染
      if((PPUMASK&vH_NES_PPU_PPUMASK_s)!=0U){
        //允许渲染
        Sprite_Renders(31U,Console);
      }else{
        Background_Renders(31U,Console);
      }

      H_NES_PPU_Process_vIncYSetX(Console,v,t_uint16);
    }
    oH_NES_CPU_Execute(4,Console);

    //line,261 line,324
    PPUMASK=Console->PPU.Register.Register[vH_NES_PPU_Register_PPUMASK];
    if((PPUMASK&(vH_NES_PPU_PPUMASK_b|vH_NES_PPU_PPUMASK_s))!=0U){
      
      //OAM预取
      MemLoc=OAM_PreFetch(line,Console);

      //MMC3 A12判定
      if(MMC3_A12_Rise!=NULL){
        PPUCTRL=Console->PPU.Register.Register[vH_NES_PPU_Register_PPUCTRL];

        //大约260~261
        if(MMC4_CountDelay>0){
          oH_NES_CPU_Execute(MMC4_CountDelay,Console);
        }
        Cycle=64-MMC4_CountDelay;
        if(((PPUCTRL&vH_NES_PPU_PPUCTRL_B)==0U)&&((MemLoc&0x01U)!=0U)){
          MMC3_A12_Rise(line,Console);
        }
        if(Cycle>0){
          Cycle-=8;
          oH_NES_CPU_Execute(8,Console);
        }
        //每两个精灵获取之间的间隙(8个精灵共7个间隙)
        for(Shift=0;Shift<6;Shift++){
          if(((MemLoc>>Shift)&0x03U)==0x02U){
            MMC3_A12_Rise(line,Console);
          }
          if(Cycle>0){
            Cycle-=8;
            oH_NES_CPU_Execute(8,Console);
          }
        }
        if(((MemLoc>>6)&0x03U)==0x02U){
          MMC3_A12_Rise(line,Console);
        }
        if(Cycle>0){
          Cycle-=8;
          oH_NES_CPU_Execute(8,Console);
        }
        if(((MemLoc&0x80U)==0U)&&((PPUCTRL&vH_NES_PPU_PPUCTRL_B)!=0U)){
          MMC3_A12_Rise(line,Console);
        }
        if(Cycle>0){
          oH_NES_CPU_Execute(Cycle,Console);
        }

      }else{
        oH_NES_CPU_Execute(64,Console);
      }
    
    }else{
      oH_NES_CPU_Execute(64,Console);
      for(BufferIndex=0;BufferIndex<256;BufferIndex++){
        Console->PPU.LineBuffer_Output[BufferIndex]=0x3FU;
      }
    }
    //输出一行的 数据
    Console->LL_Function.Console.RendersLine(Console->LL_Function.v,Console->PPU.LineBuffer_Output,line);

    //line,324 line,328
    oH_NES_CPU_Execute(4,Console);
    for(BufferIndex=0;BufferIndex<32;BufferIndex++){
      Console->PPU.Renderer.LineBuffer_Background[BufferIndex]=0U;
    }
    PPUMASK=Console->PPU.Register.Register[vH_NES_PPU_Register_PPUMASK];
    if((PPUMASK&(vH_NES_PPU_PPUMASK_b|vH_NES_PPU_PPUMASK_s))!=0U){
      
      //背景预取
      if((PPUMASK&vH_NES_PPU_PPUMASK_b)!=0U){
        Background_PreFetch_First(0U,PPUMASK,Console);
      }

      H_NES_PPU_Process_vIncX(Console,v,t_uint16);
    }

    //line,329 line,336
    oH_NES_CPU_Execute(8,Console);
    PPUMASK=Console->PPU.Register.Register[vH_NES_PPU_Register_PPUMASK];
    if((PPUMASK&(vH_NES_PPU_PPUMASK_b|vH_NES_PPU_PPUMASK_s))!=0U){
      
      //背景预取
      if((PPUMASK&vH_NES_PPU_PPUMASK_b)!=0U){
        Background_PreFetch_First(1U,PPUMASK,Console);
      }

      H_NES_PPU_Process_vIncX(Console,v,t_uint16);
    }

    //line,337 line,341
    oH_NES_CPU_Execute(4,Console);
  }

  Console->PPU.Register.Internal.IsAddXY=0;

  //240,0 331,0
  oH_NES_CPU_Execute(341+1,Console);
  //Set Vblank
  Console->PPU.Register.Register[vH_NES_PPU_Register_PPUSTATUS]|=vH_NES_PPU_PPUSTATUS_V;
  Cycle=Console->CompatibilityOption.VblankNMI_Delay;
  if(Cycle>0){
    oH_NES_CPU_Execute(Cycle,Console);
  }
  //Suspend NMI
  if((Console->PPU.Register.Register[vH_NES_PPU_Register_PPUCTRL]&vH_NES_PPU_PPUCTRL_V)!=0U){
    Console->CPU.Status|=vH_NES_CPU_Status_NMI_Suspend;
  }
  Cycle=341*70 - Cycle;
  if(Cycle>0){
    oH_NES_CPU_Execute(Cycle,Console);
  }
  
  //311,1 311,260
  //Clear Vblank
  Console->PPU.Register.Register[vH_NES_PPU_Register_PPUSTATUS]&=(~(vH_NES_PPU_PPUSTATUS_V|vH_NES_PPU_PPUSTATUS_S|vH_NES_PPU_PPUSTATUS_O));
  Console->PPU.Register.Internal.IsAddXY=-1;
  oH_NES_CPU_Execute(260,Console);
  PPUMASK=Console->PPU.Register.Register[vH_NES_PPU_Register_PPUMASK];
  if((PPUMASK&(vH_NES_PPU_PPUMASK_b|vH_NES_PPU_PPUMASK_s))!=0U){
    H_NES_PPU_Process_vIncYSetX(Console,v,t_uint16);

    //MMC3 A12判定
    if(MMC3_A12_Rise!=NULL){
      PPUCTRL=Console->PPU.Register.Register[vH_NES_PPU_Register_PPUCTRL];
      if((PPUCTRL&(vH_NES_PPU_PPUCTRL_H|vH_NES_PPU_PPUCTRL_B|vH_NES_PPU_PPUCTRL_S))==vH_NES_PPU_PPUCTRL_S){
        MMC3_A12_Rise(261U,Console);
      }else if((PPUCTRL&(vH_NES_PPU_PPUCTRL_H|vH_NES_PPU_PPUCTRL_B))==vH_NES_PPU_PPUCTRL_H){
        MMC3_A12_Rise(261U,Console);
      }
    }
  }

  //311,261 311,304
  oH_NES_CPU_Execute(44,Console);
  PPUMASK=Console->PPU.Register.Register[vH_NES_PPU_Register_PPUMASK];
  if((PPUMASK&(vH_NES_PPU_PPUMASK_b|vH_NES_PPU_PPUMASK_s))!=0U){
    //vert(v) = vert(t)
    v=Console->PPU.Register.Internal.v;
    t_uint16=Console->PPU.Register.Internal.t;
    Console->PPU.Register.Internal.v=(v&(~0x7BE0U))|(t_uint16&0x7BE0U);
  }

  //311,305 311,324
  oH_NES_CPU_Execute(20,Console);
  PPUMASK=Console->PPU.Register.Register[vH_NES_PPU_Register_PPUMASK];
  if((PPUMASK&(vH_NES_PPU_PPUMASK_b|vH_NES_PPU_PPUMASK_s))!=0U){
    //MMC3 A12判定
    if(MMC3_A12_Rise!=NULL){
      PPUCTRL=Console->PPU.Register.Register[vH_NES_PPU_Register_PPUCTRL];
      if((PPUCTRL&(vH_NES_PPU_PPUCTRL_H|vH_NES_PPU_PPUCTRL_B|vH_NES_PPU_PPUCTRL_S))==vH_NES_PPU_PPUCTRL_B){
        MMC3_A12_Rise(261U,Console);
      }
    }
  }

  //311,325 311,328
  oH_NES_CPU_Execute(4,Console);
  for(BufferIndex=0;BufferIndex<32;BufferIndex++){
    Console->PPU.Renderer.LineBuffer_Background[BufferIndex]=0U;
  }
  PPUMASK=Console->PPU.Register.Register[vH_NES_PPU_Register_PPUMASK];
  if((PPUMASK&(vH_NES_PPU_PPUMASK_b|vH_NES_PPU_PPUMASK_s))!=0U){
    
    //背景预取
    if((PPUMASK&vH_NES_PPU_PPUMASK_b)!=0U){
      Background_PreFetch_First(0U,PPUMASK,Console);
    }

    H_NES_PPU_Process_vIncX(Console,v,t_uint16);
  }

  //311,329 311,336
  oH_NES_CPU_Execute(8,Console);
  PPUMASK=Console->PPU.Register.Register[vH_NES_PPU_Register_PPUMASK];
  if((PPUMASK&(vH_NES_PPU_PPUMASK_b|vH_NES_PPU_PPUMASK_s))!=0U){
    
    //背景预取
    if((PPUMASK&vH_NES_PPU_PPUMASK_b)!=0U){
      Background_PreFetch_First(1U,PPUMASK,Console);
    }

    H_NES_PPU_Process_vIncX(Console,v,t_uint16);
  }
  

  //311,337 261,341
  oH_NES_CPU_Execute(4,Console);

#undef oH_NES_CPU_Execute

}

void H_NES_PPU_RendrsFrame_Dendy(H_NES_Console* Console){

#define oH_NES_CPU_Execute(_in_PPUCLK,_in_Console) \
  H_NES_CPU_Execute_Dendy((_in_PPUCLK)*vH_NES_PPU_Dendy_MCLKDiv,_in_Console)

  unsigned int line;

  Huint16 t_uint16;
  Hint32 Cycle;

  Hbyte PPUCTRL;
  Hbyte PPUMASK;
  Huint16 v;
  
  unsigned int BufferIndex;

  Hbyte MemLoc;
  int Shift;
  void (*MMC3_A12_Rise)(unsigned int,void*);
  Hint32 MMC4_CountDelay;


  MMC3_A12_Rise=Console->Cartridge.Option.MMC3_A12_Rise;
  MMC4_CountDelay=Console->CompatibilityOption.MMC4_CountDelay;

  //0,0 0,0
  if(Console->PPU.Renderer.IsOddFrame!=0){
    Console->PPU.Renderer.IsOddFrame=0;
  }else{
    Console->PPU.Renderer.IsOddFrame=-1;
  }
  oH_NES_CPU_Execute(1,Console);

  //0,1 0,240
  for(BufferIndex=0U;BufferIndex<30U;BufferIndex++){
    
    oH_NES_CPU_Execute(8,Console);
    PPUMASK=Console->PPU.Register.Register[vH_NES_PPU_Register_PPUMASK];
    if((PPUMASK&(vH_NES_PPU_PPUMASK_b|vH_NES_PPU_PPUMASK_s))!=0U){

      //背景预取
      if((PPUMASK&vH_NES_PPU_PPUMASK_b)!=0U){
        Background_PreFetch_Mid(BufferIndex+2U,Console);
      }

      //渲染
      Background_Renders(BufferIndex,Console);

      H_NES_PPU_Process_vIncX(Console,v,t_uint16);
    }
  }

  //0,241 0,248
  oH_NES_CPU_Execute(8,Console);
  PPUMASK=Console->PPU.Register.Register[vH_NES_PPU_Register_PPUMASK];
  if((PPUMASK&(vH_NES_PPU_PPUMASK_b|vH_NES_PPU_PPUMASK_s))!=0U){

    //背景预取
    if((PPUMASK&vH_NES_PPU_PPUMASK_b)!=0U){
      Background_PreFetch_Last(Console);
    }

    //渲染
    Background_Renders(30U,Console);

    H_NES_PPU_Process_vIncX(Console,v,t_uint16);
  }

  //0,249 0,260
  oH_NES_CPU_Execute(8,Console);
  PPUMASK=Console->PPU.Register.Register[vH_NES_PPU_Register_PPUMASK];
  if((PPUMASK&(vH_NES_PPU_PPUMASK_b|vH_NES_PPU_PPUMASK_s))!=0U){

    //渲染
    Background_Renders(31U,Console);

    H_NES_PPU_Process_vIncYSetX(Console,v,t_uint16);
  }
  oH_NES_CPU_Execute(4,Console);

  //0,261 0,324
  PPUMASK=Console->PPU.Register.Register[vH_NES_PPU_Register_PPUMASK];
  if((PPUMASK&(vH_NES_PPU_PPUMASK_b|vH_NES_PPU_PPUMASK_s))!=0U){
    
    //OAM预取
    MemLoc=OAM_PreFetch(0U,Console);

    //MMC3 A12判定
    if(MMC3_A12_Rise!=NULL){
      PPUCTRL=Console->PPU.Register.Register[vH_NES_PPU_Register_PPUCTRL];

      //大约260~261
      if(MMC4_CountDelay>0){
        oH_NES_CPU_Execute(MMC4_CountDelay,Console);
      }
      Cycle=64-MMC4_CountDelay;
      if(((PPUCTRL&vH_NES_PPU_PPUCTRL_B)==0U)&&((MemLoc&0x01U)!=0U)){
        MMC3_A12_Rise(line,Console);
      }
      if(Cycle>0){
        Cycle-=8;
        oH_NES_CPU_Execute(8,Console);
      }
      //每两个精灵获取之间的间隙(8个精灵共7个间隙)
      for(Shift=0;Shift<6;Shift++){
        if(((MemLoc>>Shift)&0x03U)==0x02U){
          MMC3_A12_Rise(line,Console);
        }
        if(Cycle>0){
          Cycle-=8;
          oH_NES_CPU_Execute(8,Console);
        }
      }
      if(((MemLoc>>6)&0x03U)==0x02U){
        MMC3_A12_Rise(line,Console);
      }
      if(Cycle>0){
        Cycle-=8;
        oH_NES_CPU_Execute(8,Console);
      }
      if(((MemLoc&0x80U)==0U)&&((PPUCTRL&vH_NES_PPU_PPUCTRL_B)!=0U)){
        MMC3_A12_Rise(line,Console);
      }
      if(Cycle>0){
        oH_NES_CPU_Execute(Cycle,Console);
      }

    }else{
      oH_NES_CPU_Execute(64,Console);
    }
  
  }else{
    oH_NES_CPU_Execute(64,Console);
    for(BufferIndex=0;BufferIndex<256;BufferIndex++){
      Console->PPU.LineBuffer_Output[BufferIndex]=0x3FU;
    }
  }
  //输出一行的 数据
  Console->LL_Function.Console.RendersLine(Console->LL_Function.v,Console->PPU.LineBuffer_Output,0);

  //0,325 0,328
  oH_NES_CPU_Execute(4,Console);
  for(BufferIndex=0;BufferIndex<32;BufferIndex++){
    Console->PPU.Renderer.LineBuffer_Background[BufferIndex]=0U;
  }
  PPUMASK=Console->PPU.Register.Register[vH_NES_PPU_Register_PPUMASK];
  if((PPUMASK&(vH_NES_PPU_PPUMASK_b|vH_NES_PPU_PPUMASK_s))!=0U){
    
    //背景预取
    if((PPUMASK&vH_NES_PPU_PPUMASK_b)!=0U){
      Background_PreFetch_First(0U,PPUMASK,Console);
    }

    H_NES_PPU_Process_vIncX(Console,v,t_uint16);
  }

  //0,329 0,336
  oH_NES_CPU_Execute(8,Console);
  PPUMASK=Console->PPU.Register.Register[vH_NES_PPU_Register_PPUMASK];
  if((PPUMASK&(vH_NES_PPU_PPUMASK_b|vH_NES_PPU_PPUMASK_s))!=0U){
    
    //背景预取
    if((PPUMASK&vH_NES_PPU_PPUMASK_b)!=0U){
      Background_PreFetch_First(1U,PPUMASK,Console);
    }

    H_NES_PPU_Process_vIncX(Console,v,t_uint16);
  }

  //0,337 0,340
  oH_NES_CPU_Execute(4,Console);




  //1,0 239,340
  for(line=1U;line<240U;line++){

    //line,0 line,0
    oH_NES_CPU_Execute(1,Console);

    //line,1 line,240
    for(BufferIndex=0U;BufferIndex<30U;BufferIndex++){
    
      oH_NES_CPU_Execute(8,Console);
      PPUMASK=Console->PPU.Register.Register[vH_NES_PPU_Register_PPUMASK];
      if((PPUMASK&(vH_NES_PPU_PPUMASK_b|vH_NES_PPU_PPUMASK_s))!=0U){

        //背景预取
        if((PPUMASK&vH_NES_PPU_PPUMASK_b)!=0U){
          Background_PreFetch_Mid(BufferIndex+2U,Console);
        }

        //渲染
        if(((PPUMASK&vH_NES_PPU_PPUMASK_s)!=0U)&&((BufferIndex!=0U)||((PPUMASK&vH_NES_PPU_PPUMASK_M)!=0U))){
          //允许渲染
          Sprite_Renders(BufferIndex,Console);
        }else{
          Background_Renders(BufferIndex,Console);
        }

        H_NES_PPU_Process_vIncX(Console,v,t_uint16);
      }
    }

    //line,241 line,248
    oH_NES_CPU_Execute(8,Console);
    PPUMASK=Console->PPU.Register.Register[vH_NES_PPU_Register_PPUMASK];
    if((PPUMASK&(vH_NES_PPU_PPUMASK_b|vH_NES_PPU_PPUMASK_s))!=0U){

      //背景预取
      if((PPUMASK&vH_NES_PPU_PPUMASK_b)!=0U){
        Background_PreFetch_Last(Console);
      }

      //渲染
      if((PPUMASK&vH_NES_PPU_PPUMASK_s)!=0U){
        //允许渲染
        Sprite_Renders(30U,Console);
      }else{
        Background_Renders(30U,Console);
      }

      H_NES_PPU_Process_vIncX(Console,v,t_uint16);
    }

    //line,249 line,260
    oH_NES_CPU_Execute(8,Console);
    PPUMASK=Console->PPU.Register.Register[vH_NES_PPU_Register_PPUMASK];
    if((PPUMASK&(vH_NES_PPU_PPUMASK_b|vH_NES_PPU_PPUMASK_s))!=0U){

      //渲染
      if((PPUMASK&vH_NES_PPU_PPUMASK_s)!=0U){
        //允许渲染
        Sprite_Renders(31U,Console);
      }else{
        Background_Renders(31U,Console);
      }

      H_NES_PPU_Process_vIncYSetX(Console,v,t_uint16);
    }
    oH_NES_CPU_Execute(4,Console);

    //line,261 line,324
    PPUMASK=Console->PPU.Register.Register[vH_NES_PPU_Register_PPUMASK];
    if((PPUMASK&(vH_NES_PPU_PPUMASK_b|vH_NES_PPU_PPUMASK_s))!=0U){
      
      //OAM预取
      MemLoc=OAM_PreFetch(line,Console);

      //MMC3 A12判定
      if(MMC3_A12_Rise!=NULL){
        PPUCTRL=Console->PPU.Register.Register[vH_NES_PPU_Register_PPUCTRL];

        //大约260~261
        if(MMC4_CountDelay>0){
          oH_NES_CPU_Execute(MMC4_CountDelay,Console);
        }
        Cycle=64-MMC4_CountDelay;
        if(((PPUCTRL&vH_NES_PPU_PPUCTRL_B)==0U)&&((MemLoc&0x01U)!=0U)){
          MMC3_A12_Rise(line,Console);
        }
        if(Cycle>0){
          Cycle-=8;
          oH_NES_CPU_Execute(8,Console);
        }
        //每两个精灵获取之间的间隙(8个精灵共7个间隙)
        for(Shift=0;Shift<6;Shift++){
          if(((MemLoc>>Shift)&0x03U)==0x02U){
            MMC3_A12_Rise(line,Console);
          }
          if(Cycle>0){
            Cycle-=8;
            oH_NES_CPU_Execute(8,Console);
          }
        }
        if(((MemLoc>>6)&0x03U)==0x02U){
          MMC3_A12_Rise(line,Console);
        }
        if(Cycle>0){
          Cycle-=8;
          oH_NES_CPU_Execute(8,Console);
        }
        if(((MemLoc&0x80U)==0U)&&((PPUCTRL&vH_NES_PPU_PPUCTRL_B)!=0U)){
          MMC3_A12_Rise(line,Console);
        }
        if(Cycle>0){
          oH_NES_CPU_Execute(Cycle,Console);
        }

      }else{
        oH_NES_CPU_Execute(64,Console);
      }
    
    }else{
      oH_NES_CPU_Execute(64,Console);
      for(BufferIndex=0;BufferIndex<256;BufferIndex++){
        Console->PPU.LineBuffer_Output[BufferIndex]=0x3FU;
      }
    }
    //输出一行的 数据
    Console->LL_Function.Console.RendersLine(Console->LL_Function.v,Console->PPU.LineBuffer_Output,line);

    //line,324 line,328
    oH_NES_CPU_Execute(4,Console);
    for(BufferIndex=0;BufferIndex<32;BufferIndex++){
      Console->PPU.Renderer.LineBuffer_Background[BufferIndex]=0U;
    }
    PPUMASK=Console->PPU.Register.Register[vH_NES_PPU_Register_PPUMASK];
    if((PPUMASK&(vH_NES_PPU_PPUMASK_b|vH_NES_PPU_PPUMASK_s))!=0U){
      
      //背景预取
      if((PPUMASK&vH_NES_PPU_PPUMASK_b)!=0U){
        Background_PreFetch_First(0U,PPUMASK,Console);
      }

      H_NES_PPU_Process_vIncX(Console,v,t_uint16);
    }

    //line,329 line,336
    oH_NES_CPU_Execute(8,Console);
    PPUMASK=Console->PPU.Register.Register[vH_NES_PPU_Register_PPUMASK];
    if((PPUMASK&(vH_NES_PPU_PPUMASK_b|vH_NES_PPU_PPUMASK_s))!=0U){
      
      //背景预取
      if((PPUMASK&vH_NES_PPU_PPUMASK_b)!=0U){
        Background_PreFetch_First(1U,PPUMASK,Console);
      }

      H_NES_PPU_Process_vIncX(Console,v,t_uint16);
    }

    //line,337 line,341
    oH_NES_CPU_Execute(4,Console);
  }

  Console->PPU.Register.Internal.IsAddXY=0;

  //240,0 311,0
  oH_NES_CPU_Execute(341*51+1,Console);
  //Set Vblank
  Console->PPU.Register.Register[vH_NES_PPU_Register_PPUSTATUS]|=vH_NES_PPU_PPUSTATUS_V;
  Cycle=Console->CompatibilityOption.VblankNMI_Delay;
  if(Cycle>0){
    oH_NES_CPU_Execute(Cycle,Console);
  }
  //Suspend NMI
  if((Console->PPU.Register.Register[vH_NES_PPU_Register_PPUCTRL]&vH_NES_PPU_PPUCTRL_V)!=0U){
    Console->CPU.Status|=vH_NES_CPU_Status_NMI_Suspend;
  }
  Cycle=341*20 - Cycle;
  if(Cycle>0){
    oH_NES_CPU_Execute(Cycle,Console);
  }
  
  //311,1 311,260
  //Clear Vblank
  Console->PPU.Register.Register[vH_NES_PPU_Register_PPUSTATUS]&=(~(vH_NES_PPU_PPUSTATUS_V|vH_NES_PPU_PPUSTATUS_S|vH_NES_PPU_PPUSTATUS_O));
  Console->PPU.Register.Internal.IsAddXY=-1;
  oH_NES_CPU_Execute(260,Console);
  PPUMASK=Console->PPU.Register.Register[vH_NES_PPU_Register_PPUMASK];
  if((PPUMASK&(vH_NES_PPU_PPUMASK_b|vH_NES_PPU_PPUMASK_s))!=0U){
    H_NES_PPU_Process_vIncYSetX(Console,v,t_uint16);

    //MMC3 A12判定
    if(MMC3_A12_Rise!=NULL){
      PPUCTRL=Console->PPU.Register.Register[vH_NES_PPU_Register_PPUCTRL];
      if((PPUCTRL&(vH_NES_PPU_PPUCTRL_H|vH_NES_PPU_PPUCTRL_B|vH_NES_PPU_PPUCTRL_S))==vH_NES_PPU_PPUCTRL_S){
        MMC3_A12_Rise(261U,Console);
      }else if((PPUCTRL&(vH_NES_PPU_PPUCTRL_H|vH_NES_PPU_PPUCTRL_B))==vH_NES_PPU_PPUCTRL_H){
        MMC3_A12_Rise(261U,Console);
      }
    }
  }

  //311,261 311,304
  oH_NES_CPU_Execute(44,Console);
  PPUMASK=Console->PPU.Register.Register[vH_NES_PPU_Register_PPUMASK];
  if((PPUMASK&(vH_NES_PPU_PPUMASK_b|vH_NES_PPU_PPUMASK_s))!=0U){
    //vert(v) = vert(t)
    v=Console->PPU.Register.Internal.v;
    t_uint16=Console->PPU.Register.Internal.t;
    Console->PPU.Register.Internal.v=(v&(~0x7BE0U))|(t_uint16&0x7BE0U);
  }

  //311,305 311,324
  oH_NES_CPU_Execute(20,Console);
  PPUMASK=Console->PPU.Register.Register[vH_NES_PPU_Register_PPUMASK];
  if((PPUMASK&(vH_NES_PPU_PPUMASK_b|vH_NES_PPU_PPUMASK_s))!=0U){
    //MMC3 A12判定
    if(MMC3_A12_Rise!=NULL){
      PPUCTRL=Console->PPU.Register.Register[vH_NES_PPU_Register_PPUCTRL];
      if((PPUCTRL&(vH_NES_PPU_PPUCTRL_H|vH_NES_PPU_PPUCTRL_B|vH_NES_PPU_PPUCTRL_S))==vH_NES_PPU_PPUCTRL_B){
        MMC3_A12_Rise(261U,Console);
      }
    }
  }

  //311,325 311,328
  oH_NES_CPU_Execute(4,Console);
  for(BufferIndex=0;BufferIndex<32;BufferIndex++){
    Console->PPU.Renderer.LineBuffer_Background[BufferIndex]=0U;
  }
  PPUMASK=Console->PPU.Register.Register[vH_NES_PPU_Register_PPUMASK];
  if((PPUMASK&(vH_NES_PPU_PPUMASK_b|vH_NES_PPU_PPUMASK_s))!=0U){
    
    //背景预取
    if((PPUMASK&vH_NES_PPU_PPUMASK_b)!=0U){
      Background_PreFetch_First(0U,PPUMASK,Console);
    }

    H_NES_PPU_Process_vIncX(Console,v,t_uint16);
  }

  //311,329 311,336
  oH_NES_CPU_Execute(8,Console);
  PPUMASK=Console->PPU.Register.Register[vH_NES_PPU_Register_PPUMASK];
  if((PPUMASK&(vH_NES_PPU_PPUMASK_b|vH_NES_PPU_PPUMASK_s))!=0U){
    
    //背景预取
    if((PPUMASK&vH_NES_PPU_PPUMASK_b)!=0U){
      Background_PreFetch_First(1U,PPUMASK,Console);
    }

    H_NES_PPU_Process_vIncX(Console,v,t_uint16);
  }
  

  //311,337 261,341
  oH_NES_CPU_Execute(4,Console);

#undef oH_NES_CPU_Execute

}




static void Background_PreFetch_First(unsigned int BufferIndex,Hbyte PPUMASK,H_NES_Console* Console){
  
  unsigned int i;
  unsigned int i_limit;

  Huint16 t_uint16;
  Huint32 t_uint32;

  Huint16 v;
  Hbyte OffsetX;
  Huint16 Pattern;
  Huint32 Attribute;
  Huint32 LowTileByte;
  Huint32 HighTileByte;
  Huint32 Tile_Pixel;
  Huint32 Buffer;


  if((Console->PPU.Register.Register[vH_NES_PPU_Register_PPUCTRL]&vH_NES_PPU_PPUCTRL_B)!=0U){
    Pattern=0x1000U;
  }else{
    Pattern=0x0000U;
  }
  OffsetX=Console->PPU.Register.Internal.x;

  v=Console->PPU.Register.Internal.v;
  Attribute=Console->PPU.NameTable[(v&0x0C00U)>>10][0x03C0U+(((v>>4)&0x0038U)|((v>>2)&0x0007U))];
  t_uint16=(v&0x0002U)|((v>>4)&0x0004U);
  Attribute=((Attribute>>t_uint16)<<2)&0x0000000CU;
  t_uint16=((Huint16)Console->PPU.NameTable[(v&0x0C00U)>>10][v&0x03FFU])<<4;
  t_uint16+=Pattern+((v>>12)&0x0007U);
  LowTileByte=Console->Cartridge.CHR_Read(t_uint16,Console);
  HighTileByte=Console->Cartridge.CHR_Read(t_uint16+8U,Console);
  
  
  //后部分
  Buffer=Console->PPU.Renderer.LineBuffer_Background[BufferIndex];
  i=0U;
  i_limit=7U-OffsetX;
  t_uint32=i_limit<<2;
  while(i<=i_limit){
    Tile_Pixel=0x1U<<i;
    Tile_Pixel=(((LowTileByte&Tile_Pixel)|((HighTileByte&Tile_Pixel)<<1))>>i);
    if(Tile_Pixel!=0U){
      Tile_Pixel|=Attribute;
      Buffer=Buffer|(Tile_Pixel<<t_uint32);
    }
    t_uint32-=4U;
    i++;
  }
  Console->PPU.Renderer.LineBuffer_Background[BufferIndex]=Buffer;
  
  //前部分
  if((OffsetX>0U)&&(BufferIndex>0U)){
    BufferIndex--;

    Buffer=Console->PPU.Renderer.LineBuffer_Background[BufferIndex];
    i=7U;
    i_limit=7U-OffsetX;
    t_uint32=(i_limit+1U)<<2;
    while(i>i_limit){
      Tile_Pixel=0x1U<<i;
      Tile_Pixel=(((LowTileByte&Tile_Pixel)|((HighTileByte&Tile_Pixel)<<1))>>i);
      if(Tile_Pixel!=0U){
        Tile_Pixel|=Attribute;
        Buffer=Buffer|(Tile_Pixel<<t_uint32);
      }
      t_uint32+=4U;
      i--;
    }
    Console->PPU.Renderer.LineBuffer_Background[BufferIndex]=Buffer;
  }

  if((PPUMASK&vH_NES_PPU_PPUMASK_m)==0U){
    Console->PPU.Renderer.LineBuffer_Background[0]=0U;//强制让背景透明
  }
}

static void Background_PreFetch_Mid(unsigned int BufferIndex,H_NES_Console* Console){

  unsigned int i;
  unsigned int i_limit;

  Huint16 t_uint16;
  Huint32 t_uint32;

  Huint16 v;
  Hbyte OffsetX;
  Huint16 Pattern;
  Huint32 Attribute;
  Huint32 LowTileByte;
  Huint32 HighTileByte;
  Huint32 Tile_Pixel;
  Huint32 Buffer;

  if((Console->PPU.Register.Register[vH_NES_PPU_Register_PPUCTRL]&vH_NES_PPU_PPUCTRL_B)!=0U){
    Pattern=0x1000U;
  }else{
    Pattern=0x0000U;
  }
  OffsetX=Console->PPU.Register.Internal.x;

  v=Console->PPU.Register.Internal.v;
  Attribute=Console->PPU.NameTable[(v&0x0C00U)>>10][0x03C0U+(((v>>4)&0x0038U)|((v>>2)&0x0007U))];
  t_uint16=(v&0x0002U)|((v>>4)&0x0004U);
  Attribute=((Attribute>>t_uint16)<<2)&0x0000000CU;
  t_uint16=((Huint16)Console->PPU.NameTable[(v&0x0C00U)>>10][v&0x03FFU])<<4;
  t_uint16+=Pattern+((v>>12)&0x0007U);
  LowTileByte=Console->Cartridge.CHR_Read(t_uint16,Console);
  HighTileByte=Console->Cartridge.CHR_Read(t_uint16+8U,Console);
  

  //后部分
  Buffer=Console->PPU.Renderer.LineBuffer_Background[BufferIndex];
  i=0U;
  i_limit=7U-OffsetX;
  t_uint32=i_limit<<2;
  while(i<=i_limit){
    Tile_Pixel=0x1U<<i;
    Tile_Pixel=(((LowTileByte&Tile_Pixel)|((HighTileByte&Tile_Pixel)<<1))>>i);
    if(Tile_Pixel!=0U){
      Tile_Pixel|=Attribute;
      Buffer=Buffer|(Tile_Pixel<<t_uint32);
    }
    t_uint32-=4U;
    i++;
  }
  Console->PPU.Renderer.LineBuffer_Background[BufferIndex]=Buffer;

  //前部分
  if(OffsetX>0U){
    BufferIndex--;

    Buffer=Console->PPU.Renderer.LineBuffer_Background[BufferIndex];
    i=7U;
    t_uint32=(i_limit+1U)<<2;
    while(i>i_limit){
      Tile_Pixel=0x1U<<i;
      Tile_Pixel=(((LowTileByte&Tile_Pixel)|((HighTileByte&Tile_Pixel)<<1))>>i);
      if(Tile_Pixel!=0U){
        Tile_Pixel|=Attribute;
        Buffer=Buffer|(Tile_Pixel<<t_uint32);
      }
      t_uint32+=4;
      i--;
    }
    Console->PPU.Renderer.LineBuffer_Background[BufferIndex]=Buffer;
  }
}

static void Background_PreFetch_Last(H_NES_Console* Console){

  unsigned int i;
  unsigned int i_limit;

  Huint16 t_uint16;
  Huint32 t_uint32;

  Huint16 v;
  Hbyte OffsetX;
  Huint16 Pattern;
  Huint32 Attribute;
  Huint32 LowTileByte;
  Huint32 HighTileByte;
  Huint32 Tile_Pixel;
  Huint32 Buffer;

  if((Console->PPU.Register.Register[vH_NES_PPU_Register_PPUCTRL]&vH_NES_PPU_PPUCTRL_B)!=0U){
    Pattern=0x1000U;
  }else{
    Pattern=0x0000U;
  }
  OffsetX=Console->PPU.Register.Internal.x;

  //前部分
  if(OffsetX>0U){
    v=Console->PPU.Register.Internal.v;
    Attribute=Console->PPU.NameTable[(v&0x0C00U)>>10][0x03C0U+(((v>>4)&0x0038U)|((v>>2)&0x0007U))];
    t_uint16=(v&0x0002U)|((v>>4)&0x0004U);
    Attribute=((Attribute>>t_uint16)<<2)&0x0000000CU;
    t_uint16=((Huint16)Console->PPU.NameTable[(v&0x0C00U)>>10][v&0x03FFU])<<4;
    t_uint16+=Pattern+((v>>12)&0x0007U);
    LowTileByte=Console->Cartridge.CHR_Read(t_uint16,Console);
    HighTileByte=Console->Cartridge.CHR_Read(t_uint16+8U,Console);


    Buffer=Console->PPU.Renderer.LineBuffer_Background[31];
    i=7U;
    i_limit=7U-OffsetX;
    t_uint32=(i_limit+1U)<<2;
    while(i>i_limit){
      Tile_Pixel=0x1U<<i;
      Tile_Pixel=(((LowTileByte&Tile_Pixel)|((HighTileByte&Tile_Pixel)<<1))>>i);
      if(Tile_Pixel!=0U){
        Tile_Pixel|=Attribute;
        Buffer=Buffer|(Tile_Pixel<<t_uint32);
      }
      t_uint32+=4U;
      i--;
    }
    Console->PPU.Renderer.LineBuffer_Background[31]=Buffer;
  }
}

static void Background_Renders(unsigned int BufferIndex,H_NES_Console* Console){

  Huint32 Buffer;

  Huint32 TileBuffer_Mask;

  Hbyte* Palettes;
  Hbyte* Output;


  Buffer=Console->PPU.Renderer.LineBuffer_Background[BufferIndex];

  Palettes=&Console->PPU.Palettes[0];
  Output=&Console->PPU.LineBuffer_Output[BufferIndex<<3];
  TileBuffer_Mask=0x0000000FU;

  if((Console->PPU.Register.Register[vH_NES_PPU_Register_PPUMASK]&vH_NES_PPU_PPUMASK_Gray)==0U){
    Output[0]=Palettes[Buffer&TileBuffer_Mask];
    TileBuffer_Mask<<=4;
    Output[1]=Palettes[(Buffer&TileBuffer_Mask)>>4];
    TileBuffer_Mask<<=4;
    Output[2]=Palettes[(Buffer&TileBuffer_Mask)>>8];
    TileBuffer_Mask<<=4;
    Output[3]=Palettes[(Buffer&TileBuffer_Mask)>>12];
    TileBuffer_Mask<<=4;
    Output[4]=Palettes[(Buffer&TileBuffer_Mask)>>16];
    TileBuffer_Mask<<=4;
    Output[5]=Palettes[(Buffer&TileBuffer_Mask)>>20];
    TileBuffer_Mask<<=4;
    Output[6]=Palettes[(Buffer&TileBuffer_Mask)>>24];
    TileBuffer_Mask<<=4;
    Output[7]=Palettes[(Buffer&TileBuffer_Mask)>>28];
  }else{
    Output[0]=Palettes[Buffer&TileBuffer_Mask]&0x30U;
    TileBuffer_Mask<<=4;
    Output[1]=Palettes[(Buffer&TileBuffer_Mask)>>4]&0x30U;
    TileBuffer_Mask<<=4;
    Output[2]=Palettes[(Buffer&TileBuffer_Mask)>>8]&0x30U;
    TileBuffer_Mask<<=4;
    Output[3]=Palettes[(Buffer&TileBuffer_Mask)>>12]&0x30U;
    TileBuffer_Mask<<=4;
    Output[4]=Palettes[(Buffer&TileBuffer_Mask)>>16]&0x30U;
    TileBuffer_Mask<<=4;
    Output[5]=Palettes[(Buffer&TileBuffer_Mask)>>20]&0x30U;
    TileBuffer_Mask<<=4;
    Output[6]=Palettes[(Buffer&TileBuffer_Mask)>>24]&0x30U;
    TileBuffer_Mask<<=4;
    Output[7]=Palettes[(Buffer&TileBuffer_Mask)>>28]&0x30U;
  }

}

static Hbyte OAM_PreFetch(unsigned int line,H_NES_Console* Console){

  int i;
  int Count;
  Hbyte MemLoc;

  Huint16 t_uint16;

  Huint16 Pattern;
  unsigned int y;
  Hbyte LowTileByte;
  Hbyte HighTileByte;
  Hbyte Attributes;
  int x;
  int xMod8;
  int xDiv8;
  unsigned int Offset;
  
  H_NES_PPU_SubOAMInfo* SubOAMInfo;
  Hbyte OAM_Count;

  Count=0;
  MemLoc=0U;


  //清空SubOAM
  for(i=0;i<32;i++){
    SubOAMInfo=&Console->PPU.Renderer.SubOAMInfo[i];
    SubOAMInfo->OAM_Count=0U;
    SubOAMInfo->ExistSprite0=0U;
  }

  Pattern=Console->PPU.Register.Register[vH_NES_PPU_Register_PPUCTRL];
  if((Pattern&vH_NES_PPU_PPUCTRL_H)!=0U){
    //8x16
    

    //精灵0
    y=Console->PPU.OAM[0];
    if(line>=y){
      Offset=line-y;
      if(Offset<16U){
        //精灵0可显示


        t_uint16=(Huint16)Console->PPU.OAM[1];
        Attributes=Console->PPU.OAM[2];
        if((Attributes&0x80U)!=0U){
          //垂直翻转
          Offset=15U-Offset;
        }
        if(Offset<8U){
          if((t_uint16&0x0001U)==0U){
            t_uint16=(t_uint16<<4)+Offset;
          }else{
            MemLoc|=0x01U;
            t_uint16=0x1000U+((t_uint16&(~0x0001U))<<4)+Offset;
          }
        }else{
          Offset-=8U;
          if((t_uint16&0x0001U)==0U){
            t_uint16=0x0010U+(t_uint16<<4)+Offset;
          }else{
            MemLoc|=0x01U;
            t_uint16=0x1010U+((t_uint16&(~0x0001U))<<4)+Offset;
          }
        }

        if((Attributes&0x40U)!=0U){
          //水平翻转
          LowTileByte=ReverseBitTable[Console->Cartridge.CHR_Read(t_uint16,Console)];
          HighTileByte=ReverseBitTable[Console->Cartridge.CHR_Read(t_uint16+8U,Console)];
        }else{
          LowTileByte=Console->Cartridge.CHR_Read(t_uint16,Console);
          HighTileByte=Console->Cartridge.CHR_Read(t_uint16+8U,Console);
        }


        Console->PPU.Renderer.SubOAMData[0].LowTileByte=LowTileByte;
        Console->PPU.Renderer.SubOAMData[0].HighTileByte=HighTileByte;
        Console->PPU.Renderer.SubOAMData[0].Attributes=Attributes;


        x=Console->PPU.OAM[3];
        xMod8=(int)(((unsigned int)x)&0x00000007U);
        xDiv8=(int)(((unsigned int)x)>>3);
        if(xMod8==0){

          SubOAMInfo=&Console->PPU.Renderer.SubOAMInfo[xDiv8];
          OAM_Count=SubOAMInfo->OAM_Count;
          SubOAMInfo->Info[OAM_Count].SubOAMDataIndex=0;
          SubOAMInfo->Info[OAM_Count].OffsetX=0;
          SubOAMInfo->OAM_Count=OAM_Count+1U;
          SubOAMInfo->ExistSprite0=0xFFU;

        }else{

          SubOAMInfo=&Console->PPU.Renderer.SubOAMInfo[xDiv8];
          OAM_Count=SubOAMInfo->OAM_Count;
          SubOAMInfo->Info[OAM_Count].SubOAMDataIndex=0;
          SubOAMInfo->Info[OAM_Count].OffsetX=(Hint8)xMod8;
          SubOAMInfo->OAM_Count=OAM_Count+1U;
          SubOAMInfo->ExistSprite0=0xFFU;

          if(xDiv8<31){
            SubOAMInfo=&SubOAMInfo[1];
            OAM_Count=SubOAMInfo->OAM_Count;
            SubOAMInfo->Info[OAM_Count].SubOAMDataIndex=0;
            SubOAMInfo->Info[OAM_Count].OffsetX=((Hint8)xMod8)-8;
            SubOAMInfo->OAM_Count=OAM_Count+1U;
            SubOAMInfo->ExistSprite0=0xFFU;
          }

        }

        Count++;
      }
    }


    //剩余的精灵
    for(i=4;i<256;i+=4){
      
      y=Console->PPU.OAM[i];
      if(line>=y){
        Offset=line-y;
        if(Offset<16U){
          //找到要显示的精灵

          if(Count>7){
            Console->PPU.Register.Register[vH_NES_PPU_Register_PPUSTATUS]|=vH_NES_PPU_PPUSTATUS_O;//精灵溢出
            return MemLoc;
          }


          t_uint16=(Huint16)Console->PPU.OAM[i+1];
          Attributes=Console->PPU.OAM[i+2];
          if((Attributes&0x80U)!=0U){
            //垂直翻转
            Offset=15U-Offset;
          }
          if(Offset<8U){
            if((t_uint16&0x0001U)==0U){
              t_uint16=(t_uint16<<4)+(Huint16)Offset;
            }else{
              MemLoc|=0x01U<<Count;
              t_uint16=0x1000U+((t_uint16&(~0x0001U))<<4)+(Huint16)Offset;
            }
          }else{
            Offset-=8U;
            if((t_uint16&0x0001U)==0U){
              t_uint16=0x0010U+(t_uint16<<4)+(Huint16)Offset;
            }else{
              MemLoc|=0x01U<<Count;
              t_uint16=0x1010U+((t_uint16&(~0x0001U))<<4)+(Huint16)Offset;
            }
          }

          if((Attributes&0x40U)!=0U){
            //水平翻转
            LowTileByte=ReverseBitTable[Console->Cartridge.CHR_Read(t_uint16,Console)];
            HighTileByte=ReverseBitTable[Console->Cartridge.CHR_Read(t_uint16+8U,Console)];
          }else{
            LowTileByte=Console->Cartridge.CHR_Read(t_uint16,Console);
            HighTileByte=Console->Cartridge.CHR_Read(t_uint16+8U,Console);
          }


          Console->PPU.Renderer.SubOAMData[Count].LowTileByte=LowTileByte;
          Console->PPU.Renderer.SubOAMData[Count].HighTileByte=HighTileByte;
          Console->PPU.Renderer.SubOAMData[Count].Attributes=Attributes;


          x=Console->PPU.OAM[i+3];
          xMod8=(int)(((unsigned int)x)&0x00000007U);
          xDiv8=(int)(((unsigned int)x)>>3);
          if(xMod8==0){

            SubOAMInfo=&Console->PPU.Renderer.SubOAMInfo[xDiv8];
            OAM_Count=SubOAMInfo->OAM_Count;
            SubOAMInfo->Info[OAM_Count].SubOAMDataIndex=(Hbyte)Count;
            SubOAMInfo->Info[OAM_Count].OffsetX=0;
            SubOAMInfo->OAM_Count=OAM_Count+1U;

          }else{

            SubOAMInfo=&Console->PPU.Renderer.SubOAMInfo[xDiv8];
            OAM_Count=SubOAMInfo->OAM_Count;
            SubOAMInfo->Info[OAM_Count].SubOAMDataIndex=(Hbyte)Count;
            SubOAMInfo->Info[OAM_Count].OffsetX=xMod8;
            SubOAMInfo->OAM_Count=OAM_Count+1U;

            if(xDiv8<31){
              SubOAMInfo=&SubOAMInfo[1];
              OAM_Count=SubOAMInfo->OAM_Count;
              SubOAMInfo->Info[OAM_Count].SubOAMDataIndex=(Hbyte)Count;
              SubOAMInfo->Info[OAM_Count].OffsetX=((Hint8)xMod8)-8;
              SubOAMInfo->OAM_Count=OAM_Count+1U;
            }

          }

          Count++;
        }
      }

    }
    
    if(Count<8U){
      MemLoc|=((0x01U<<(8-Count))-0x01U)<<Count;
    }
  }else{
    if((Pattern&vH_NES_PPU_PPUCTRL_S)!=0U){
      Pattern=0x1000U;
      MemLoc=0xFFU;
    }else{
      Pattern=0x0000U;
    }
    //8*8
    

    //精灵0
    y=Console->PPU.OAM[0];
    if(line>=y){
      Offset=line-y;
      if(Offset<8U){
        //精灵0可显示


        t_uint16=((Huint16)Console->PPU.OAM[1])<<4;
        Attributes=Console->PPU.OAM[2];
        if((Attributes&0x80U)!=0U){
          //垂直翻转
          t_uint16+=Pattern+((0x0007U-(Huint16)Offset)&0x0007U);
        }else{
          t_uint16+=Pattern+(Huint16)Offset;
        }
        if((Attributes&0x40U)!=0U){
          //水平翻转
          LowTileByte=ReverseBitTable[Console->Cartridge.CHR_Read(t_uint16,Console)];
          HighTileByte=ReverseBitTable[Console->Cartridge.CHR_Read(t_uint16+8U,Console)];
        }else{
          LowTileByte=Console->Cartridge.CHR_Read(t_uint16,Console);
          HighTileByte=Console->Cartridge.CHR_Read(t_uint16+8U,Console);
        }


        Console->PPU.Renderer.SubOAMData[0].LowTileByte=LowTileByte;
        Console->PPU.Renderer.SubOAMData[0].HighTileByte=HighTileByte;
        Console->PPU.Renderer.SubOAMData[0].Attributes=Attributes;


        x=Console->PPU.OAM[3];
        xMod8=(int)(((unsigned int)x)&0x00000007U);
        xDiv8=(int)(((unsigned int)x)>>3);
        if(xMod8==0){

          SubOAMInfo=&Console->PPU.Renderer.SubOAMInfo[xDiv8];
          OAM_Count=SubOAMInfo->OAM_Count;
          SubOAMInfo->Info[OAM_Count].SubOAMDataIndex=0;
          SubOAMInfo->Info[OAM_Count].OffsetX=0;
          SubOAMInfo->OAM_Count=OAM_Count+1U;
          SubOAMInfo->ExistSprite0=0xFFU;

        }else{

          SubOAMInfo=&Console->PPU.Renderer.SubOAMInfo[xDiv8];
          OAM_Count=SubOAMInfo->OAM_Count;
          SubOAMInfo->Info[OAM_Count].SubOAMDataIndex=0;
          SubOAMInfo->Info[OAM_Count].OffsetX=(Hint8)xMod8;
          SubOAMInfo->OAM_Count=OAM_Count+1U;
          SubOAMInfo->ExistSprite0=0xFFU;

          if(xDiv8<31){
            SubOAMInfo=&SubOAMInfo[1];
            OAM_Count=SubOAMInfo->OAM_Count;
            SubOAMInfo->Info[OAM_Count].SubOAMDataIndex=0;
            SubOAMInfo->Info[OAM_Count].OffsetX=((Hint8)xMod8)-8;
            SubOAMInfo->OAM_Count=OAM_Count+1U;
            SubOAMInfo->ExistSprite0=0xFFU;
          }

        }

        Count++;
      }
    }


    //剩余的精灵
    for(i=4;i<256;i+=4){
      
      y=Console->PPU.OAM[i];
      if(line>=y){
        Offset=line-y;
        if(Offset<8U){
          //找到要显示的精灵

          if(Count>7){
            Console->PPU.Register.Register[vH_NES_PPU_Register_PPUSTATUS]|=vH_NES_PPU_PPUSTATUS_O;//精灵溢出
            return MemLoc;
          }


          t_uint16=((Huint16)Console->PPU.OAM[i+1])<<4;
          Attributes=Console->PPU.OAM[i+2];
          if((Attributes&0x80U)!=0U){
            //垂直翻转
            t_uint16+=Pattern+((0x0007U-(Huint16)Offset)&0x0007U);
          }else{
            t_uint16+=Pattern+(Huint16)Offset;
          }
          if((Attributes&0x40U)!=0U){
            //水平翻转
            LowTileByte=ReverseBitTable[Console->Cartridge.CHR_Read(t_uint16,Console)];
            HighTileByte=ReverseBitTable[Console->Cartridge.CHR_Read(t_uint16+8U,Console)];
          }else{
            LowTileByte=Console->Cartridge.CHR_Read(t_uint16,Console);
            HighTileByte=Console->Cartridge.CHR_Read(t_uint16+8U,Console);
          }


          Console->PPU.Renderer.SubOAMData[Count].LowTileByte=LowTileByte;
          Console->PPU.Renderer.SubOAMData[Count].HighTileByte=HighTileByte;
          Console->PPU.Renderer.SubOAMData[Count].Attributes=Attributes;


          x=Console->PPU.OAM[i+3];
          xMod8=(int)(((unsigned int)x)&0x00000007U);
          xDiv8=(int)(((unsigned int)x)>>3);
          if(xMod8==0){

            SubOAMInfo=&Console->PPU.Renderer.SubOAMInfo[xDiv8];
            OAM_Count=SubOAMInfo->OAM_Count;
            SubOAMInfo->Info[OAM_Count].SubOAMDataIndex=(Hbyte)Count;
            SubOAMInfo->Info[OAM_Count].OffsetX=0;
            SubOAMInfo->OAM_Count=OAM_Count+1U;

          }else{

            SubOAMInfo=&Console->PPU.Renderer.SubOAMInfo[xDiv8];
            OAM_Count=SubOAMInfo->OAM_Count;
            SubOAMInfo->Info[OAM_Count].SubOAMDataIndex=(Hbyte)Count;
            SubOAMInfo->Info[OAM_Count].OffsetX=xMod8;
            SubOAMInfo->OAM_Count=OAM_Count+1U;

            if(xDiv8<31){
              SubOAMInfo=&SubOAMInfo[1];
              OAM_Count=SubOAMInfo->OAM_Count;
              SubOAMInfo->Info[OAM_Count].SubOAMDataIndex=(Hbyte)Count;
              SubOAMInfo->Info[OAM_Count].OffsetX=((Hint8)xMod8)-8;
              SubOAMInfo->OAM_Count=OAM_Count+1U;
            }

          }

          Count++;
        }
      }

    }
    
  }

  return MemLoc;
}

static void Sprite_Renders(unsigned int BufferIndex,H_NES_Console* Console){
  
  unsigned int i;
  unsigned int i_limit;

  Hint8 t_int8;
  Huint32 t_uint32;

  Huint32 Attribute;
  Huint32 LowTileByte;
  Huint32 HighTileByte;
  Huint32 Tile_Pixel;
  Huint32 TileBuffer_Mask;
  Huint32 Buffer;
  Huint32 SpriteBuffer;
  Huint32 SpriteBuffer_Mask;

  H_NES_PPU_SubOAMInfo* SubOAMInfo;
  unsigned int SubOAM_OAMIndex;
  unsigned int SubOAM_Count;
  Huint16 Sprite_Attributes;

  Hbyte* Palettes;
  Hbyte* Sprite_Palettes;
  Hbyte* Output;


  SubOAMInfo=&Console->PPU.Renderer.SubOAMInfo[BufferIndex];
  SubOAM_Count=SubOAMInfo->OAM_Count;
  if(SubOAM_Count>0U){
    SubOAMInfo->OAM_Count=0U;

    
    Buffer=Console->PPU.Renderer.LineBuffer_Background[BufferIndex];
    SpriteBuffer=0x0U;
    SpriteBuffer_Mask=0U;
    
    if(SubOAMInfo->ExistSprite0!=0U){
      //存在Sprite0
      SubOAMInfo->ExistSprite0=0U;


      //精灵0渲染
      //i=SubOAMInfo->Info[0].SubOAMDataIndex;
      LowTileByte=Console->PPU.Renderer.SubOAMData[0].LowTileByte;
      HighTileByte=Console->PPU.Renderer.SubOAMData[0].HighTileByte;
      Sprite_Attributes=Console->PPU.Renderer.SubOAMData[0].Attributes;
      t_int8=SubOAMInfo->Info[0].OffsetX;
      if(t_int8<0){
        t_int8=-t_int8;

        i=0U;
        i_limit=7U-t_int8;
        t_uint32=i_limit<<2;
      }else{
        i=t_int8;
        i_limit=7U;
        t_uint32=7U<<2;
      }
      
      Attribute=(Sprite_Attributes&0x03U)<<2;
      if((Sprite_Attributes&0x20U)!=0U){
        //在背景后

        while(i<=i_limit){
          Tile_Pixel=0x1U<<i;
          Tile_Pixel=(((LowTileByte&Tile_Pixel)|((HighTileByte&Tile_Pixel)<<1))>>i);
          if(Tile_Pixel!=0U){
            //不透明
            TileBuffer_Mask=0xFU<<t_uint32;
            //if((SpriteBuffer&TileBuffer_Mask)==0U){//这是PPU的一个特性 PPU关于优先级的一些奇妙特性由它引起 同时它使得ID低的精灵显示在前面
              Tile_Pixel|=Attribute;
              SpriteBuffer|=Tile_Pixel<<t_uint32;
              if((Buffer&TileBuffer_Mask)!=0U){
                //背景不透明 精灵像素不能显示

                //Sprite 0 Hit
                Console->PPU.Register.Register[vH_NES_PPU_Register_PPUSTATUS]|=vH_NES_PPU_PPUSTATUS_S;
              }else{
                SpriteBuffer_Mask|=TileBuffer_Mask;
              }
            //}
          }
          t_uint32-=4;
          i++;
        }

      }else{
        //在背景前

        while(i<=i_limit){
          Tile_Pixel=0x1U<<i;
          Tile_Pixel=(((LowTileByte&Tile_Pixel)|((HighTileByte&Tile_Pixel)<<1))>>i);
          if(Tile_Pixel!=0U){
            //不透明
            TileBuffer_Mask=0xFU<<t_uint32;
            //if((SpriteBuffer&TileBuffer_Mask)==0U){//这是PPU的一个特性 PPU关于优先级的一些奇妙特性由它引起 同时它使得ID低的精灵显示在前面
              SpriteBuffer_Mask|=TileBuffer_Mask;
              Tile_Pixel|=Attribute;
              SpriteBuffer|=Tile_Pixel<<t_uint32;
              if((Buffer&TileBuffer_Mask)!=0U){

                //Sprite 0 Hit
                Console->PPU.Register.Register[vH_NES_PPU_Register_PPUSTATUS]|=vH_NES_PPU_PPUSTATUS_S;
              }
            //}
          }
          t_uint32-=4;
          i++;
        }

      }


      SubOAM_OAMIndex=1U;
    }else{
      SubOAM_OAMIndex=0U;
    }


    //剩余精灵渲染循环
    while(SubOAM_OAMIndex<SubOAM_Count){
    
      i=SubOAMInfo->Info[SubOAM_OAMIndex].SubOAMDataIndex;
      LowTileByte=Console->PPU.Renderer.SubOAMData[i].LowTileByte;
      HighTileByte=Console->PPU.Renderer.SubOAMData[i].HighTileByte;
      Sprite_Attributes=Console->PPU.Renderer.SubOAMData[i].Attributes;
      t_int8=SubOAMInfo->Info[SubOAM_OAMIndex].OffsetX;
      if(t_int8<0){
        t_int8=-t_int8;

        i=0U;
        i_limit=7U-t_int8;
        t_uint32=i_limit<<2;
      }else{
        i=t_int8;
        i_limit=7U;
        t_uint32=7U<<2;
      }
      
      Attribute=(Sprite_Attributes&0x03U)<<2;
      if((Sprite_Attributes&0x20U)!=0U){
        //在背景后

        while(i<=i_limit){
          Tile_Pixel=0x1U<<i;
          Tile_Pixel=(((LowTileByte&Tile_Pixel)|((HighTileByte&Tile_Pixel)<<1))>>i);
          if(Tile_Pixel!=0U){
            //不透明
            TileBuffer_Mask=0xFU<<t_uint32;
            if((SpriteBuffer&TileBuffer_Mask)==0U){//这是PPU的一个特性 PPU关于优先级的一些奇妙特性由它引起 同时它使得ID低的精灵显示在前面
              Tile_Pixel|=Attribute;
              SpriteBuffer|=Tile_Pixel<<t_uint32;
              if((Buffer&TileBuffer_Mask)==0U){
                //精灵能够显示
                SpriteBuffer_Mask|=TileBuffer_Mask;
              }
            }
          }
          t_uint32-=4;
          i++;
        }

      }else{
        //在背景前

        while(i<=i_limit){
          Tile_Pixel=0x1U<<i;
          Tile_Pixel=(((LowTileByte&Tile_Pixel)|((HighTileByte&Tile_Pixel)<<1))>>i);
          if(Tile_Pixel!=0U){
            //不透明
            TileBuffer_Mask=0xFU<<t_uint32;
            if((SpriteBuffer&TileBuffer_Mask)==0U){//这是PPU的一个特性 PPU关于优先级的一些奇妙特性由它引起 同时它使得ID低的精灵显示在前面
              SpriteBuffer_Mask|=TileBuffer_Mask;
              Tile_Pixel|=Attribute;
              SpriteBuffer|=Tile_Pixel<<t_uint32;
            }
          }
          t_uint32-=4;
          i++;
        }

      }

      SubOAM_OAMIndex++;
    }

    


    //混合背景和精灵
    Palettes=&Console->PPU.Palettes[0];
    Sprite_Palettes=&Palettes[16];
    Output=&Console->PPU.LineBuffer_Output[BufferIndex<<3];
    TileBuffer_Mask=0x0000000FU;

    if((Console->PPU.Register.Register[vH_NES_PPU_Register_PPUMASK]&vH_NES_PPU_PPUMASK_Gray)==0U){
      if((SpriteBuffer_Mask&TileBuffer_Mask)==0U){
        Output[0]=Palettes[Buffer&TileBuffer_Mask];
      }else{
        Output[0]=Sprite_Palettes[SpriteBuffer&TileBuffer_Mask];
      }
      TileBuffer_Mask<<=4;
      if((SpriteBuffer_Mask&TileBuffer_Mask)==0U){
        Output[1]=Palettes[(Buffer&TileBuffer_Mask)>>4];
      }else{
        Output[1]=Sprite_Palettes[(SpriteBuffer&TileBuffer_Mask)>>4];
      }
      TileBuffer_Mask<<=4;
      if((SpriteBuffer_Mask&TileBuffer_Mask)==0U){
        Output[2]=Palettes[(Buffer&TileBuffer_Mask)>>8];
      }else{
        Output[2]=Sprite_Palettes[(SpriteBuffer&TileBuffer_Mask)>>8];
      }
      TileBuffer_Mask<<=4;
      if((SpriteBuffer_Mask&TileBuffer_Mask)==0U){
        Output[3]=Palettes[(Buffer&TileBuffer_Mask)>>12];
      }else{
        Output[3]=Sprite_Palettes[(SpriteBuffer&TileBuffer_Mask)>>12];
      }
      TileBuffer_Mask<<=4;
      if((SpriteBuffer_Mask&TileBuffer_Mask)==0U){
        Output[4]=Palettes[(Buffer&TileBuffer_Mask)>>16];
      }else{
        Output[4]=Sprite_Palettes[(SpriteBuffer&TileBuffer_Mask)>>16];
      }
      TileBuffer_Mask<<=4;
      if((SpriteBuffer_Mask&TileBuffer_Mask)==0U){
        Output[5]=Palettes[(Buffer&TileBuffer_Mask)>>20];
      }else{
        Output[5]=Sprite_Palettes[(SpriteBuffer&TileBuffer_Mask)>>20];
      }
      TileBuffer_Mask<<=4;
      if((SpriteBuffer_Mask&TileBuffer_Mask)==0U){
        Output[6]=Palettes[(Buffer&TileBuffer_Mask)>>24];
      }else{
        Output[6]=Sprite_Palettes[(SpriteBuffer&TileBuffer_Mask)>>24];
      }
      TileBuffer_Mask<<=4;
      if((SpriteBuffer_Mask&TileBuffer_Mask)==0U){
        Output[7]=Palettes[(Buffer&TileBuffer_Mask)>>28];
      }else{
        Output[7]=Sprite_Palettes[(SpriteBuffer&TileBuffer_Mask)>>28];
      }
    }else{
      if((SpriteBuffer_Mask&TileBuffer_Mask)==0U){
        Output[0]=Palettes[Buffer&TileBuffer_Mask]&0x30U;
      }else{
        Output[0]=Sprite_Palettes[SpriteBuffer&TileBuffer_Mask]&0x30U;
      }
      TileBuffer_Mask<<=4;
      if((SpriteBuffer_Mask&TileBuffer_Mask)==0U){
        Output[1]=Palettes[(Buffer&TileBuffer_Mask)>>4]&0x30U;
      }else{
        Output[1]=Sprite_Palettes[(SpriteBuffer&TileBuffer_Mask)>>4]&0x30U;
      }
      TileBuffer_Mask<<=4;
      if((SpriteBuffer_Mask&TileBuffer_Mask)==0U){
        Output[2]=Palettes[(Buffer&TileBuffer_Mask)>>8]&0x30U;
      }else{
        Output[2]=Sprite_Palettes[(SpriteBuffer&TileBuffer_Mask)>>8]&0x30U;
      }
      TileBuffer_Mask<<=4;
      if((SpriteBuffer_Mask&TileBuffer_Mask)==0U){
        Output[3]=Palettes[(Buffer&TileBuffer_Mask)>>12]&0x30U;
      }else{
        Output[3]=Sprite_Palettes[(SpriteBuffer&TileBuffer_Mask)>>12]&0x30U;
      }
      TileBuffer_Mask<<=4;
      if((SpriteBuffer_Mask&TileBuffer_Mask)==0U){
        Output[4]=Palettes[(Buffer&TileBuffer_Mask)>>16]&0x30U;
      }else{
        Output[4]=Sprite_Palettes[(SpriteBuffer&TileBuffer_Mask)>>16]&0x30U;
      }
      TileBuffer_Mask<<=4;
      if((SpriteBuffer_Mask&TileBuffer_Mask)==0U){
        Output[5]=Palettes[(Buffer&TileBuffer_Mask)>>20]&0x30U;
      }else{
        Output[5]=Sprite_Palettes[(SpriteBuffer&TileBuffer_Mask)>>20]&0x30U;
      }
      TileBuffer_Mask<<=4;
      if((SpriteBuffer_Mask&TileBuffer_Mask)==0U){
        Output[6]=Palettes[(Buffer&TileBuffer_Mask)>>24]&0x30U;
      }else{
        Output[6]=Sprite_Palettes[(SpriteBuffer&TileBuffer_Mask)>>24]&0x30U;
      }
      TileBuffer_Mask<<=4;
      if((SpriteBuffer_Mask&TileBuffer_Mask)==0U){
        Output[7]=Palettes[(Buffer&TileBuffer_Mask)>>28]&0x30U;
      }else{
        Output[7]=Sprite_Palettes[(SpriteBuffer&TileBuffer_Mask)>>28]&0x30U;
      }
    }


    
  }else{
    //无精灵 输出背景

    Buffer=Console->PPU.Renderer.LineBuffer_Background[BufferIndex];

    Palettes=&Console->PPU.Palettes[0];
    Output=&Console->PPU.LineBuffer_Output[BufferIndex<<3];
    TileBuffer_Mask=0x0000000FU;

    if((Console->PPU.Register.Register[vH_NES_PPU_Register_PPUMASK]&vH_NES_PPU_PPUMASK_Gray)==0U){
      Output[0]=Palettes[Buffer&TileBuffer_Mask];
      TileBuffer_Mask<<=4;
      Output[1]=Palettes[(Buffer&TileBuffer_Mask)>>4];
      TileBuffer_Mask<<=4;
      Output[2]=Palettes[(Buffer&TileBuffer_Mask)>>8];
      TileBuffer_Mask<<=4;
      Output[3]=Palettes[(Buffer&TileBuffer_Mask)>>12];
      TileBuffer_Mask<<=4;
      Output[4]=Palettes[(Buffer&TileBuffer_Mask)>>16];
      TileBuffer_Mask<<=4;
      Output[5]=Palettes[(Buffer&TileBuffer_Mask)>>20];
      TileBuffer_Mask<<=4;
      Output[6]=Palettes[(Buffer&TileBuffer_Mask)>>24];
      TileBuffer_Mask<<=4;
      Output[7]=Palettes[(Buffer&TileBuffer_Mask)>>28];
    }else{
      Output[0]=Palettes[Buffer&TileBuffer_Mask]&0x30U;
      TileBuffer_Mask<<=4;
      Output[1]=Palettes[(Buffer&TileBuffer_Mask)>>4]&0x30U;
      TileBuffer_Mask<<=4;
      Output[2]=Palettes[(Buffer&TileBuffer_Mask)>>8]&0x30U;
      TileBuffer_Mask<<=4;
      Output[3]=Palettes[(Buffer&TileBuffer_Mask)>>12]&0x30U;
      TileBuffer_Mask<<=4;
      Output[4]=Palettes[(Buffer&TileBuffer_Mask)>>16]&0x30U;
      TileBuffer_Mask<<=4;
      Output[5]=Palettes[(Buffer&TileBuffer_Mask)>>20]&0x30U;
      TileBuffer_Mask<<=4;
      Output[6]=Palettes[(Buffer&TileBuffer_Mask)>>24]&0x30U;
      TileBuffer_Mask<<=4;
      Output[7]=Palettes[(Buffer&TileBuffer_Mask)>>28]&0x30U;
    }

  }
  
}



